home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 24 / Amiga Format AFCD24 (Feb 1998, Issue 108).iso / -seriously_amiga- / shareware / programming / other / unsqsh / unsqsh.c next >
C/C++ Source or Header  |  1998-01-12  |  8KB  |  461 lines

  1. /*
  2.  
  3.   portable code to decrunch XPK-SQSH files
  4.   written from "xpksqsh.library 1.10 (6.3.94)"
  5.  
  6.   (24.12.97) jah@fh-zwickau.de
  7.   
  8.   tested with sas6.51(m68k) gcc2.7.2(i386) gcc2.7.2(sparc)
  9.  
  10. */
  11.  
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14.  
  15. typedef unsigned char byte;
  16. void unpack(byte *src, byte *dst, int len);
  17.  
  18. int main(int ac,char *av[]) {
  19.   unsigned char *src;
  20.   unsigned char *dst;
  21.   int srclen;
  22.   int dstlen;
  23.  
  24.   if ('X' != getchar() ||
  25.       'P' != getchar() ||
  26.       'K' != getchar() ||
  27.       'F' != getchar()) {
  28.     fprintf(stderr,"no XPK file\n");
  29.     exit(1);
  30.   }
  31.   srclen  = getchar(); srclen <<= 8;
  32.   srclen |= getchar(); srclen <<= 8;
  33.   srclen |= getchar(); srclen <<= 8;
  34.   srclen |= getchar();
  35.   fprintf(stderr,"source file length      : %d bytes\n",srclen+8);
  36.   if ('S' != getchar() ||
  37.       'Q' != getchar() ||
  38.       'S' != getchar() ||
  39.       'H' != getchar()) {
  40.     fprintf(stderr,"no SQSH file\n");
  41.     exit(1);
  42.   }
  43.   dstlen  = getchar(); dstlen <<= 8;
  44.   dstlen |= getchar(); dstlen <<= 8;
  45.   dstlen |= getchar(); dstlen <<= 8;
  46.   dstlen |= getchar();
  47.   fprintf(stderr,"destination file length : %d bytes\n",dstlen);
  48.  
  49.   src=(unsigned char*)malloc(srclen);
  50.   dst=(unsigned char*)malloc(dstlen+100);
  51.   if (src==NULL || dst==NULL) {
  52.      fprintf(stderr,"not enough memory\n");
  53.      exit(1);
  54.   }
  55.  
  56.   if (1 != fread(src,srclen-8,1,stdin)) {
  57.     fprintf(stderr,"error reading source file\n");
  58.     exit(1);
  59.   }
  60.  
  61.   unpack(src,dst,dstlen);
  62.  
  63.   if (1 != fwrite(dst,dstlen,1,stdout)) {
  64.     fprintf(stderr,"error writing destination file\n");
  65.     exit(1);
  66.   }
  67.     
  68.   free(src);
  69.   free(dst);
  70.  
  71.   return 0;
  72. }
  73.  
  74.  
  75. int bfextu(byte *p,int bo,int bc) {
  76.   int r;
  77.   
  78.   p += bo / 8;
  79.   r = *(p++);
  80.   r <<= 8;
  81.   r |= *(p++);
  82.   r <<= 8;
  83.   r |= *p;
  84.   r <<= bo % 8;
  85.   r &= 0xffffff;
  86.   r >>= 24 - bc;
  87.  
  88.   return r;
  89. }
  90.  
  91. int bfexts(byte *p,int bo,int bc) {
  92.   int r;
  93.   
  94.   p += bo / 8;
  95.   r = *(p++);
  96.   r <<= 8;
  97.   r |= *(p++);
  98.   r <<= 8;
  99.   r |= *p;
  100.   r <<= (bo % 8) + 8;
  101.   r >>= 32 - bc;
  102.  
  103.   return r;
  104. }
  105.  
  106. /*
  107. ;    0    LONG    "XPKF"
  108. ;    4    LONG    file size - 8
  109. ;    8    LONG    "SQSH"
  110. ;   12    LONG    unpacked size
  111. ;  $10    QUAD    original file header
  112. ;  $20    WORD
  113. ;  $22    WORD
  114. ;  $24
  115. ;
  116. ;    0    WORD    ratio?
  117. ;    2    WORD    ?
  118. ;    4    WORD    packed chunk size starting from offset 6, long aligned
  119. ;    6    WORD    unpacked chunk size
  120. ;    8    WORD    unpacked chunk size
  121. ;   10    LABEL    bitstream...
  122. */
  123.  
  124. void unpack(byte *src, byte *dst, int len) {
  125.   int d0,d1,d2,d3,d4,d5,d6,a2,a5;
  126.   int rat,u,cp,cup1,cup2;
  127.   byte *a4,*a6,*c;
  128.   byte a3[] = { 2,3,4,5,6,7,8,0,3,2,4,5,6,7,8,0,4,3,5,2,6,7,8,0,5,4,
  129.         6,2,3,7,8,0,6,5,7,2,3,4,8,0,7,6,8,2,3,4,5,0,8,7,6,2,3,4,5,0 };
  130.    
  131.   c = src + 20;
  132.   while (len) {
  133.     rat = *c++; rat <<= 8; rat |= *c++;        /* ratio ? */
  134.     u = *c++; u <<= 8; u |= *c++;        /* ? */
  135.     cp = *c++; cp <<= 8; cp |= *c++;        /* packed */
  136.     cup1 = *c++; cup1 <<= 8; cup1 |= *c++;    /* unpacked */
  137.     cup2 = *c++; cup2 <<= 8; cup2 |= *c++;    /* unpacked */
  138.     src = c;
  139. /*
  140. fprintf(stderr,"c=%p rat=%04x u=%04x cp=%04x cup1=%04x cup2=%04x\n",c,rat,u,cp,cup1,cup2);
  141. */
  142.     if (cup1 != cup2) {
  143.       c -= 8;
  144.       continue;
  145.     }
  146.  
  147.     len -= cup2;
  148.     cp = (cp + 3) & 0xfffc;
  149.     c += cp - 2;
  150.  
  151.     a6 = dst + cup2;
  152.     d0 = d1 = d2 = d3 = a2 = 0;
  153.   
  154.     d3 = *(src++);
  155.     *(dst++) = d3;
  156. l6c6:    if (d1 >= 8) goto l6dc;
  157.     if (bfextu(src,d0,1)) goto l75a;
  158.     d0 += 1;
  159.     d5 = 0;
  160.     d6 = 8;
  161.     goto l734;
  162.   
  163. l6dc:    if (bfextu(src,d0,1)) goto l726;
  164.     d0 += 1;
  165.     if (! bfextu(src,d0,1)) goto l75a;
  166.     d0 += 1;
  167.     if (bfextu(src,d0,1)) goto l6f6;
  168.     d6 = 2;
  169.     goto l708;
  170.  
  171. l6f6:    d0 += 1;
  172.     if (! bfextu(src,d0,1)) goto l706;
  173.     d6 = bfextu(src,d0,3);
  174.     d0 += 3;
  175.     goto l70a;
  176.   
  177. l706:    d6 = 3;
  178. l708:    d0 += 1;
  179. l70a:    d6 = *(a3 + (8*a2) + d6 -17);
  180.     if (d6 != 8) goto l730;
  181. l718:    if (d2 < 20) goto l722;
  182.     d5 = 1;
  183.     goto l732;
  184.   
  185. l722:    d5 = 0;
  186.     goto l734;
  187.  
  188. l726:    d0 += 1;
  189.     d6 = 8;
  190.     if (d6 == a2) goto l718;
  191.     d6 = a2;
  192. l730:    d5 = 4;
  193. l732:    d2 += 8;
  194. l734:    d4 = bfexts(src,d0,d6);
  195.     d0 += d6;
  196.     d3 -= d4;
  197.     *dst++ = d3;
  198.     d5--;
  199.     if (d5 != -1) goto l734;
  200.     if (d1 == 31) goto l74a;
  201.     d1 += 1;
  202. l74a:    a2 = d6;
  203. l74c:    d6 = d2;
  204.     d6 >>= 3;
  205.     d2 -= d6;
  206.     if (dst < a6) goto l6c6;
  207.     /*
  208.     if (dst != a6) {
  209.       fprintf(stderr,"fatal dst=%p a6=%p\n",dst,a6);
  210.       exit(1);
  211.     }
  212.     */
  213.     dst = a6;
  214.   }
  215.   return;
  216.  
  217. l75a:    d0 += 1;
  218.     if (bfextu(src,d0,1)) goto l766;
  219.     d4 = 2;
  220.     goto l79e;
  221.   
  222. l766:    d0 += 1;
  223.     if (bfextu(src,d0,1)) goto l772;
  224.     d4 = 4;
  225.     goto l79e;
  226.  
  227. l772:    d0 += 1;
  228.     if (bfextu(src,d0,1)) goto l77e;
  229.     d4 = 6;
  230.     goto l79e;
  231.  
  232. l77e:    d0 += 1;
  233.     if (bfextu(src,d0,1)) goto l792;
  234.     d0 += 1;
  235.     d6 = bfextu(src,d0,3);
  236.     d0 += 3;
  237.     d6 += 8;
  238.     goto l7a8;
  239.   
  240. l792:    d0 += 1;
  241.     d6 = bfextu(src,d0,5);
  242.     d0 += 5;
  243.     d4 = 16;
  244.     goto l7a6;
  245.   
  246. l79e:    d0 += 1;
  247.     d6 = bfextu(src,d0,1);
  248.     d0 += 1;
  249. l7a6:    d6 += d4;
  250. l7a8:    if (bfextu(src,d0,1)) goto l7c4;
  251.     d0 += 1;
  252.     if (bfextu(src,d0,1)) goto l7bc;
  253.     d5 = 8;
  254.     a5 = 0;
  255.     goto l7ca;
  256.  
  257. l7bc:    d5 = 14;
  258.     a5 = -0x1100;
  259.     goto l7ca;
  260.  
  261. l7c4:    d5 = 12;
  262.     a5 = -0x100;
  263. l7ca:    d0 += 1;
  264.     d4 = bfextu(src,d0,d5);
  265.     d0 += d5;
  266.     d6 -= 3;
  267.     if (d6 < 0) goto l7e0;
  268.     if (d6 == 0) goto l7da;
  269.     d1 -= 1;
  270. l7da:    d1 -= 1;
  271.     if (d1 >= 0) goto l7e0;
  272.     d1 = 0;
  273. l7e0:    d6 += 2;
  274.     a4 = -1 + dst + a5 - d4;
  275. l7ex:    *dst++ = *a4++;
  276.     d6--;
  277.     if (d6 != -1) goto l7ex;
  278.     d3 = *(--a4);
  279.     goto l74c;
  280. }
  281.  
  282. /*
  283.  
  284. Unpack    move.l    a6,-(sp)
  285.     movea.l    a0,a6
  286.     movea.l    (a6),a0
  287.     movea.l    (8,a6),a1
  288.     moveq    #0,d7
  289.     move.w    (a0)+,d7
  290.     move.l    d7,($10,a6)
  291.     bsr.b    lbc0006b0
  292.     moveq    #0,d0
  293.     movea.l    (sp)+,a6
  294.     rts
  295.  
  296. lbc0006b0    movea.l    a1,a6
  297.     adda.l    d7,a6
  298.     moveq    #0,d0
  299.     moveq    #0,d1
  300.     moveq    #0,d2
  301.     moveq    #0,d3
  302.     suba.w    a2,a2
  303.     lea    (data_a3,pc),a3
  304.     move.b    (a0)+,d3
  305.     move.b    d3,(a1)+
  306. lbc0006c6    cmp.w    #8,d1
  307.     bcc.b    lbc0006dc
  308.     bftst    (a0){d0:1}
  309.     bne.w    lbc00075a
  310.     addq.l    #1,d0
  311.     moveq    #0,d5
  312.     moveq    #8,d6
  313.     bra.b    lbc000734
  314.  
  315. lbc0006dc    bftst    (a0){d0:1}
  316.     bne.b    lbc000726
  317.     addq.l    #1,d0
  318.     bftst    (a0){d0:1}
  319.     beq.b    lbc00075a
  320.     addq.l    #1,d0
  321.     bftst    (a0){d0:1}
  322.     bne.b    lbc0006f6
  323.     moveq    #2,d6
  324.     bra.b    lbc000708
  325.  
  326. lbc0006f6    addq.l    #1,d0
  327.     bftst    (a0){d0:1}
  328.     beq.b    lbc000706
  329.     bfextu    (a0){d0:3},d6
  330.     addq.l    #3,d0
  331.     bra.b    lbc00070a
  332.  
  333. lbc000706    moveq    #3,d6
  334. lbc000708    addq.l    #1,d0
  335. lbc00070a    lea    (-$10,a3,a2.w*8),a4
  336.     move.b    (-1,a4,d6.w),d6
  337.     cmp.w    #8,d6
  338.     bne.b    lbc000730
  339. lbc000718    cmp.w    #$14,d2
  340.     bcs.b    lbc000722
  341.     moveq    #1,d5
  342.     bra.b    lbc000732
  343.  
  344. lbc000722    moveq    #0,d5
  345.     bra.b    lbc000734
  346.  
  347. lbc000726    addq.l    #1,d0
  348.     moveq    #8,d6
  349.     cmpa.w    d6,a2
  350.     beq.b    lbc000718
  351.     move.l    a2,d6
  352. lbc000730    moveq    #4,d5
  353. lbc000732    addq.w    #8,d2
  354. lbc000734    bfexts    (a0){d0:d6},d4
  355.     add.l    d6,d0
  356.     sub.b    d4,d3
  357.     move.b    d3,(a1)+
  358.     dbra    d5,lbc000734
  359.     cmp.w    #$1f,d1
  360.     beq.b    lbc00074a
  361.     addq.w    #1,d1
  362. lbc00074a    movea.w    d6,a2
  363. lbc00074c    move.w    d2,d6
  364.     lsr.w    #3,d6
  365.     sub.w    d6,d2
  366.     cmpa.l    a6,a1
  367.     blt.w    lbc0006c6
  368.     rts
  369.  
  370. lbc00075a    addq.l    #1,d0
  371.     bftst    (a0){d0:1}
  372.     bne.b    lbc000766
  373.     moveq    #2,d4
  374.     bra.b    lbc00079e
  375.  
  376. lbc000766    addq.l    #1,d0
  377.     bftst    (a0){d0:1}
  378.     bne.b    lbc000772
  379.     moveq    #4,d4
  380.     bra.b    lbc00079e
  381.  
  382. lbc000772    addq.l    #1,d0
  383.     bftst    (a0){d0:1}
  384.     bne.b    lbc00077e
  385.     moveq    #6,d4
  386.     bra.b    lbc00079e
  387.  
  388. lbc00077e    addq.l    #1,d0
  389.     bftst    (a0){d0:1}
  390.     bne.b    lbc000792
  391.     addq.l    #1,d0
  392.     bfextu    (a0){d0:3},d6
  393.     addq.l    #3,d0
  394.     addq.l    #8,d6
  395.     bra.b    lbc0007a8
  396.  
  397. lbc000792    addq.l    #1,d0
  398.     bfextu    (a0){d0:5},d6
  399.     addq.l    #5,d0
  400.     moveq    #$10,d4
  401.     bra.b    lbc0007a6
  402.  
  403. lbc00079e    addq.l    #1,d0
  404.     bfextu    (a0){d0:1},d6
  405.     addq.l    #1,d0
  406. lbc0007a6    add.w    d4,d6
  407. lbc0007a8    bftst    (a0){d0:1}
  408.     bne.b    lbc0007c4
  409.     addq.l    #1,d0
  410.     bftst    (a0){d0:1}
  411.     bne.b    lbc0007bc
  412.     moveq    #8,d5
  413.     suba.w    a5,a5
  414.     bra.b    lbc0007ca
  415.  
  416. lbc0007bc    moveq    #14,d5
  417.     movea.w    #$ef00,a5
  418.     bra.b    lbc0007ca
  419.  
  420. lbc0007c4    moveq    #12,d5
  421.     movea.w    #$ff00,a5
  422. lbc0007ca    addq.l    #1,d0
  423.     bfextu    (a0){d0:d5},d4
  424.     add.l    d5,d0
  425.     subq.w    #3,d6
  426.     bcs.b    lbc0007e0
  427.     beq.b    lbc0007da
  428.     subq.w    #1,d1
  429. lbc0007da    subq.w    #1,d1
  430.     bge.b    lbc0007e0
  431.     moveq    #0,d1
  432. lbc0007e0    addq.w    #2,d6
  433.     lea    (-1,a1,a5.w),a4
  434.     suba.w    d4,a4
  435.     lsr.w    #1,d6
  436.     bcc.b    lbc0007ee
  437. lbc0007ec    move.b    (a4)+,(a1)+
  438. lbc0007ee    move.b    (a4)+,(a1)+
  439.     dbra    d6,lbc0007ec
  440.     move.b    -(a4),d3
  441.     bra.w    lbc00074c
  442.  
  443. data_a3    dc.l    $2030405
  444.     dc.l    $6070800
  445.     dc.l    $3020405
  446.     dc.l    $6070800
  447.     dc.l    $4030502
  448.     dc.l    $6070800
  449.     dc.l    $5040602
  450.     dc.l    $3070800
  451.     dc.l    $6050702
  452.     dc.l    $3040800
  453.     dc.l    $7060802
  454.     dc.l    $3040500
  455.     dc.l    $8070602
  456.     dc.l    $3040500
  457.     dc.b    0
  458.     dc.b    0
  459.  
  460. */
  461.